package websocket;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SendingThread extends Thread
{
    private final static Logger LOGGER = Logger.getLogger(SendingThread.class
        .getName());
    
    private Socket client;
    private WebSocketConnection wsConnection;
    private Framedata[] frames;
    private boolean closeConnection;
 
    public SendingThread(WebSocketConnection connection, Socket client, Framedata[] frames)
    {
        this(connection, client, frames, false);
    }
    
    public SendingThread(WebSocketConnection connection, Socket client, Framedata[] frames, boolean closeConnection)
    {
        if (connection == null || client == null || frames == null)
        {
            throw new IllegalArgumentException("WebsocketConnection, Client socket or frames array is null");
        }
        if (frames.length < 1)
        {
            throw new IllegalArgumentException("The sending thread must receive at least one frame to send. Empty array was passed.");
        }
        this.wsConnection = connection;
        this.client = client;
        this.frames = frames;
        this.closeConnection = closeConnection;
    }
    
    @Override
    public void run()
    {
        super.run();
        
        LOGGER.log(Level.FINER, "Sending {0} frames to client {1}:{2}",
                   new Object[]{frames.length, client.getInetAddress(), client.getPort()});
        
        try
        {
            BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
            
            for (Framedata frame : frames)
            {
                LOGGER.log(Level.FINEST, "Frame type: {0}", frame.getOpcode());
                out.write(frame.getBytes());
                out.flush();
            }
            
            if (closeConnection)
            {
                LOGGER.log(Level.FINEST,
                           "Closing socket connection with client {0}:{1} as requested",
                           new Object[]{frames.length, client.getInetAddress(), client.getPort()});
                
                out.close();
                client.close();
                wsConnection.setClosedState();
            }
        }
        catch (IOException ex)
        {
            LOGGER.log(Level.FINER, "IOException {0}", ex.getMessage());
            wsConnection.onBrokenConnection(ex);
        }
    }
    
}
